package com.powernode.util;

import cn.hutool.core.collection.IterChain;
import com.powernode.config.MinioConfig;
import com.powernode.dto.Result;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.RemoveObjectsArgs;
import io.minio.errors.*;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * minio的工具类，文件上传和删除
 **/
@Component
public class MinioUtil {
    //注入minio的客户端对象，因为不是所有引入公共模块的微服务都需要使用该工具类，所以将自动注入关闭(required=false)，在需要使用的微服务中手动引入
    @Autowired(required = false)
    private MinioClient client;

    @Autowired(required = false)
    private MinioConfig config;



    /**
     * 文件上传
     **/

    public Result upload(MultipartFile file, String directory) {
        String bucketName = config.getBucket_name();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM/dd");
        String now = sdf.format(new Date());
        String filename = UUID.randomUUID()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String objectName = directory+"/"+now+"/"+filename;
        try {

            client.putObject(PutObjectArgs.builder().bucket(bucketName)
                                                    .object(objectName)
                                                    .stream(file.getInputStream(), file.getSize(), -1)
                                                    .contentType(file.getContentType())
                                                    .build());
            Map<String, String> data = new HashMap<>();
            data.put("name",objectName);
            data.put("url",config.getEndpoint()+"/"+bucketName+"/"+objectName);
            return Result.success("上传文件成功",data);
        } catch (Exception e) {
            return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
        }
    }

    /**
     * 文件删除
     **/
    public Result removeFile(String filename){
        String bucketName = config.getBucket_name();
        try {
            client.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(filename).build());
            return Result.success("文件删除成功",null);
        } catch (Exception e) {
            return Result.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), "文件删除失败，请检查是否存在");
        }
    }

    /**
     * 文件批量删除
     **/
    public Result removeBatch(List<String> files){
        String bucketName = config.getBucket_name();
        List<DeleteObject> objects = files.stream().map(DeleteObject::new).collect(Collectors.toList());
        Iterable<io.minio.Result<DeleteError>> errorResultList = client.removeObjects(RemoveObjectsArgs.
                                                                                                        builder().
                                                                                                        bucket(bucketName).
                                                                                                        objects(objects).
                                                                                                        build());
        for (io.minio.Result<DeleteError> errorResult : errorResultList) {

            DeleteError error = null;
            try {
                error = errorResult.get();
            } catch (Exception e) {
                String msg = "Error in deleting object " + error.objectName() + ": " + error.message();
                return Result.failure(HttpStatus.NO_CONTENT.value(), msg);
            }

        }
        //errorResultList.forEach(System.out::println);
        return Result.success("删除成功",null);
    }
}
